﻿using System;
using System.Collections.Generic;
using System.Text;

namespace PostRequestFactory.Core
{
    /// <summary>
    /// This class corresponds to a post request body
    /// plus some headers whose content is strongly coupled to the request body
    /// </summary>
    public class PostRequest
    {
        internal const string BinaryDataPlaceHolder = "$$&&##@@BinaryDataPlaceHolder@@##&&$$";

        public virtual string BoundaryValue { get; private set; }
        internal bool AllowBodyContentOnlyAsBytes { get; set; }
        internal List<byte[]> BinaryParamsContent { get; set; }

        public PostRequest()
        {
            BoundaryValue = "---------------------------" + Guid.NewGuid().ToString();
            BodyBuilder = new StringBuilder();
            BinaryParamsContent = new List<byte[]>();
        }

        internal StringBuilder BodyBuilder { get; private set; }

        /// <summary>
        /// Returns content of the 'Content-Length' header
        /// </summary>
        public string ContentLengthHeader { get { return string.Format("{0};", BodyAsBytes.Length); } }
        
        /// <summary>
        /// Content of the 'Content-Type' header
        /// </summary>
        public string ContentTypeHeader { get; internal set; }

        /// <summary>
        /// Get body content as a string
        /// </summary>
        public string Body
        {
            get
            {
                if (AllowBodyContentOnlyAsBytes)
                {
                    return Encoding.UTF8.GetString(BodyAsBytes);
                }

                return BodyBuilder.ToString();
            }
        }

        /// <summary>
        /// Returns body content as an array of bytes
        /// </summary>
        public byte[] BodyAsBytes
        {
            get
            {
                var bodyBytes = new List<byte>();

                //inject binary params values into the body content
                if (AllowBodyContentOnlyAsBytes)
                {
                    var bodyParts = BodyBuilder.ToString().Split(new[] {BinaryDataPlaceHolder}, StringSplitOptions.None);

                    for (var i = 0; i < bodyParts.Length; i++)
                    {
                        //add body content as bytes
                        bodyBytes.AddRange(Encoding.UTF8.GetBytes(bodyParts[i]));

                        if (BinaryParamsContent.Count > i)
                        {
                            //inject param content as bytes
                            bodyBytes.AddRange(BinaryParamsContent[i]);
                        }
                    }

                    return bodyBytes.ToArray();
                }

                return Encoding.UTF8.GetBytes(BodyBuilder.ToString());
            }
        }

    }
}
